package com.mzy.basics.test.cloneTwoChange;

/**
 * @author Ives
 * * @date 2022/1/26
 */
public class PersonApp {

  /**
   * 浅拷贝也可以实现对象克隆，从这名字你或许可以知道，这种拷贝一定存在某种缺陷，是的，它就是存在一定的缺陷，先来看看浅拷贝的定义：
   * 如果原型对象的成员变量是值类型，将复制一份给克隆对象，也就是说在堆中拥有独立的空间；如果原型对象的成员变量是引用类型，
   * 则将引用对象的地址复制一份给克隆对象，也就是说原型对象和克隆对象的成员变量指向相同的内存地址。换句话说，在浅克隆中，
   * 当对象被复制时只复制它本身和其中包含的值类型的成员变量，而引用类型的成员对象并没有复制
   *
   */
  public static void main(String[] args) throws Exception {
    // 初始化一个对象
    Person person = new Person("张三",20,"123456@qq.com","我是张三");
    // 复制对象
    Person person1 = (Person) person.clone();
    // 改变 person1 的属性值
    person1.setName("我是张三的克隆对象");
    // 修改 person age 的值
    person1.setAge(22);
    System.out.println("person对象："+person);
    System.out.println();
    System.out.println("person1对象："+person1);

    System.out.println(person == person1);

    /**
     * 看到这个结果，你是否有所质疑呢？说好的引用对象只是拷贝了地址，为啥修改了 person1 对象的 name 属性值，
     * person 对象没有改变？这里就是一个非常重要的知识点了，，原因在于：String、Integer 等包装类都是不可变的对象，
     * 当需要修改不可变对象的值时，需要在内存中生成一个新的对象来存放新的值，然后将原来的引用指向新的地址，
     * 所以在这里我们修改了 person1 对象的 name 属性值，person1 对象的 name 字段指向了内存中新的 name 对象，
     * 但是我们并没有改变 person 对象的 name 字段的指向，所以 person 对象的 name 还是指向内存中原来的 name 地址，也就没有变化
     *
     */

  }
}
